function [xstar, indO] = simplexCore(A_1, Sa, b, c, indI)
%                  SIMPLEXCORE
% Parte principal del algoritmo del Simplex. Supone que todas las
% condiciones (B = I, no negatividad) se cumplen. No se preocupa por
% cuales son variables artificiales y cuales de holgura. Se dedica a
% resolver el problema de minimizacion que se tiene.
% Supone que las variables basicas siempre vienen 'hasta la 
% derecha'
% Todos los vectores son columnas
% 
% usage:        simplexCore(A_1, Sa, b, c)
%      donde:
%
%        indO := arreglo de indices (salida).
%      xstar := solucion optima del problema.
%       A_1 := Matriz que contiene las restricciones del problema
%         Sa := Matriz que contiene los vectores de las holguras
%              siempre va a ser cuadrada con valores (0, -1, 1)
%         b := vector 'Lado Derecho' de las restricciones
%         c := vector de costOs.
%      indI := vector de indices (entrada)
% 
%                                   - Marcela Maldonado Figueroa -
%                                     - Pedro Orozco del Pino -
%                                    - Jose Alonso Solis Lemus -
%

fprintf('\n Entro a simplexCore\n');
A = [A_1 Sa];
[m,n] = size(A);
% B = Sa;
B = A(:,(n-m+1):n);
N = A(:,1:(n-m));
cb = c((n-m+1):n);
cn = c(1:(n-m));


xb = (B\b) ;
xn = zeros((n-m),1);
z0 = cb'*xb;

% Calculo de las ZjCj que corresponde al vector que contiene todas 
% (zj-cj)'s 
ZjCj = cb'*(B\N)-cn';

% Calculo del maximo de las (zj-cj)'s 
maxZjCj = max(ZjCj);
% entra en la base (en caso de ser positivo)
entra = find(maxZjCj(1)==ZjCj);

if maxZjCj <= 0
    % se llego a la solucion optima.
    xstar = xb;
    indO = indI;
else
    if maxZjCj > 0
        % Veamos cual sale y cual entra en la base
            sale = simplexCambioBase(N, B, xb, entra(1));
            if sale ~= 0 
                % intercambio columnas de A
                colE = A(:,entra(1));
                A(:,entra(1)) = A(:,sale);
                A(:,sale) = colE;
                % intercambio indices de arreglo
                indI([entra(1) sale]) = indI([sale entra(1)]);
                c([entra(1) sale]) = c([sale entra(1)]);
                % se vuelve a llamar a simplexCore
                [xstar, indO] = simplexCore(A(:,1:(n-m)),...
                A(:,(n-m+1):n), b, c, indI);
            else
                % solucion no acotada
                xstar = [xb;-1];
                indO = indI;
            end
    else
        %
        xstar =-1;
        indO=-1;
    end
    % comentario inutil
    fprintf('\n Sali de simplexCore\n');
    
end
% Terminado, el programa encuentra la solucion optima 
